package io.renren.modules.work.controller;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import io.renren.common.utils.DateUtils;
import io.renren.common.utils.ErrorCode;
import io.renren.common.utils.FileUploadUtils;
import io.renren.common.utils.R;
import io.renren.modules.work.entity.ScFileEntity;
import io.renren.modules.work.entity.ScProjectEntity;
import io.renren.modules.work.response.RestResponse;
import io.renren.modules.work.response.RestResponses;
import io.renren.modules.work.service.IFileService;
import io.renren.modules.work.service.ScFileService;
import io.renren.modules.work.service.ScProjectService;
import io.renren.vo.*;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;
import org.apache.poi.util.IOUtils;
import org.apache.poi.util.StringUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.ResourceUtils;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.*;
import java.net.InetAddress;
import java.net.UnknownHostException;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;

/**
 * 文件上传
 */
@Slf4j
@RestController
@RequestMapping( "/file")
@RequiredArgsConstructor
public class FileController {

    private final IFileService fileService;
    @Value("${server.port}")
    private String port;
    @Value("${server.servlet.context-path}")
    private String context;

    @Value("${file-save-path}")
    private String fileLocation;
    @Autowired
    private ScFileService scFileService;
    @Autowired
    private ScProjectService scProjectService;
    @Value("${serverIP}")
    private String serverIp;
    @Value("${ImgServerIP}")
    private String imgServerIP;
    @Value("${ImgServerPort}")
    private String imgServerPort;
    @Value("${ImgUrl}")
    private String imgUrl;
    /**
     * 普通上传方式上传文件：用于小文件的上传，等待时间短，不会产生配置数据
     *
     * @param file
     * @return
     */
    @PostMapping("/upload")
    public RestResponse<String> uploadFiles(MultipartFile file) {
        int i =  1/0;
        if (file.isEmpty()) {
            return RestResponses.newFailResponse(ErrorCode.INVALID_PARAMETER, "文件不能为空");
        }
        return RestResponses.newResponseFromResult(fileService.uploadFiles(file));
    }


    /**
     * 上传图片
     * @param multipartFile
     * @return
     */
    @RequestMapping("/upPic")
    @ResponseBody
    @Transactional
    public R upPic(@RequestParam("file")MultipartFile multipartFile,
                   @RequestParam(required = false,value = "projectdtlid") String projectdtlid,
                   @RequestParam(required = false,value = "fileType") String fileType,
                   @RequestParam(required = false,value = "sourceid")String sourceid,
                   @RequestParam(required = false,value = "sourcetable")String sourcetable) {
        FileVo fileVo = FileUploadUtils.upload(multipartFile);
        ScFileEntity scFileEntity = new ScFileEntity();
        scFileEntity.setFilename(fileVo.getFilename());
        scFileEntity.setRealfilename(fileVo.getOriginalFilename());
        scFileEntity.setCretime(new Date());
        scFileEntity.setProjectdtlid(projectdtlid);

        scFileEntity.setFiletype(StringUtils.isBlank(fileType)?0:Integer.parseInt(fileType));
        scFileEntity.setSourceid(sourceid);
        scFileEntity.setSourcetable(sourcetable);

        scFileService.save(scFileEntity);
        return R.ok().put("fileName",fileVo.getFilename());
    }

    /**
     * 显示图片
     * @return
     */
    @RequestMapping("/getPic")
    @ResponseBody
    @Transactional
    public R getPic(@RequestBody PicDTO picDTO) throws UnknownHostException {
        List<PicVo> picVos = new ArrayList<>();
        String projectdtlid = picDTO.getProjectdtlid();
        int fileType = picDTO.getFileType();
        QueryWrapper<ScFileEntity> scFileEntityQueryWrapper = new QueryWrapper<>();
        scFileEntityQueryWrapper.eq("filetype",fileType);
        if(StringUtils.isNotBlank(projectdtlid)){
            scFileEntityQueryWrapper.eq("projectdtlid",projectdtlid);
        }
        if(StringUtils.isNotBlank(picDTO.getSourceid())){
            scFileEntityQueryWrapper.eq("sourceid",picDTO.getSourceid());
        }
        if(StringUtils.isNotBlank(picDTO.getSourcetable())){
            scFileEntityQueryWrapper.eq("sourcetable",picDTO.getSourcetable());
        }

        List<ScFileEntity> list = scFileService.list(scFileEntityQueryWrapper);
        if(list.size()>0){
            for (ScFileEntity scFileEntity : list) {
                PicVo picVo = new PicVo();
                picVo.setFileId(scFileEntity.getFileid());
                String realfilename = scFileEntity.getRealfilename();
                picVo.setName(realfilename);
                    picVo.setUrl(imgUrl+scFileEntity.getFilename());
                picVo.setRealName(scFileEntity.getFilename());
                picVo.setCretime(scFileEntity.getCretime());
                //获取文件后缀名,判断是否为图片
                if(realfilename.endsWith(".png")||realfilename.endsWith(".jpg")||realfilename.endsWith(".jpeg")||realfilename.endsWith(".jpeg")) {
                    picVo.setIsPhoto(true);
                }else {
                    picVo.setIsPhoto(false);
                }

                picVos.add(picVo);



            }
        }
        return R.ok().put("data",picVos);

    }
    /**
     * 删除图片
     */
    @RequestMapping("/deletePic")
    @ResponseBody
    public R deletePic(@RequestBody DeletePicDTO deletePicDTO) {
        //删除数据库中的数据
        scFileService.removeById(deletePicDTO.getFileId());
        //删除服务器中的
        try {
            File file = new File(fileLocation,deletePicDTO.getFileName());
            if(file.exists()){
                file.delete();
            }
        }catch (Exception e){
            e.printStackTrace();
            return R.error("未找到该文件");
        }
        return R.ok();

    }

    /**
     * 删除图片
     */
    @RequestMapping("/deletePicForApp")
    @ResponseBody
    @Transactional
    public R deletePicForApp(@RequestBody DeletePicDTO deletePicDTO)  {
        //删除数据库中的数据
        scFileService.removeById(deletePicDTO.getFileId());

        return R.ok();

    }


    /**
     * 下载文件
     */
    @PostMapping("/download")
    public void download(HttpServletResponse response,@RequestBody DownloadFileDTO downloadFileDTO) throws  Exception {
        ServletOutputStream out = null;
        try{
            List<String> fileIds = downloadFileDTO.getFileId();
            String fileName = "";
            String fileId = fileIds.get(0);
            ScFileEntity scfile = scFileService.getById(fileId);
            fileName = scfile.getRealfilename();
            FileInputStream fileInputStream = new FileInputStream(fileLocation+downloadFileDTO.getFileName().get(0));
            final ByteArrayOutputStream output = new ByteArrayOutputStream();
            IOUtils.copy(fileInputStream,output);
            byte[] buff = new byte[1024];
            BufferedInputStream bis = new BufferedInputStream(new ByteArrayInputStream(output.toByteArray()));
            // 设置Response容器的编码
            response.setCharacterEncoding("UTF-8");
            // 不同类型的文件对应不同的MIME类型
            response.setContentType("application/octet-stream; charset=UTF-8");
            response.addHeader("content-disposition",
                    "attachment;fileName="+java.net.URLEncoder.encode(fileName, "UTF-8"));
            response.setHeader("Access-Control-Expose-Headers","content-disposition");
            out = response.getOutputStream();
            int i;
            while ((i = bis.read(buff)) != -1) {

                out.write(buff, 0, i);

                out.flush();

            }
        }catch (Exception e){
            e.printStackTrace();
            throw new RuntimeException();
        }finally {
            out.flush();
            out.close();
        }

    }

    /**
     * 压缩文件列表
     */

    public void toZip(List<File> srcFiles, OutputStream out) throws RuntimeException {
        long start = System.currentTimeMillis();
        ZipOutputStream zos = null;
        try {
            zos = new ZipOutputStream(out);
            for (File srcFile : srcFiles) {
                byte[] buf = new byte[2 * 1024];
                zos.putNextEntry(new ZipEntry(srcFile.getName()));
                int len;
                FileInputStream in = new FileInputStream(srcFile);
                while ((len = in.read(buf)) != -1) {
                    zos.write(buf, 0, len);
                }
                zos.closeEntry();
                in.close();
            }
            long end = System.currentTimeMillis();
            System.out.println("压缩完成，耗时：" + (end - start) + " ms");
        } catch (Exception e) {
            throw new RuntimeException("zip error from ZipUtils", e);
        } finally {
            if (zos != null) {
                try {
                    zos.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }

    }



}
